package cn.catkic.location;



import android.annotation.SuppressLint;
import android.content.Context;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.Bundle;
import android.util.Log;

import org.apache.cordova.CordovaInterface;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CallbackContext;

import org.apache.cordova.CordovaWebView;
import org.apache.cordova.PluginResult;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONStringer;
import org.json.JSONTokener;

/**
 * This class echoes a string called from JavaScript.
 */
@SuppressLint("MissingPermission")
public class CatkicLocation extends CordovaPlugin {


    private LocationManager lm;
    private CallbackContext callbackContext;

    private long accuracy;

    @Override
    public void initialize(CordovaInterface cordova, CordovaWebView webView) {
        super.initialize(cordova, webView);
    }

    @Override
    public boolean execute(String action, JSONArray args, CallbackContext callbackContext)  {
        lm = (LocationManager) cordova.getActivity().getSystemService(Context.LOCATION_SERVICE);
        this.callbackContext = callbackContext;
        try {
            if (action.equals("coolMethod")) {
                String message = args.getString(0);
                this.coolMethod(message, callbackContext);
                return true;
            } else if ("getLocation".equals(action)) {
                if (!checkGPS()) {
                    return true;
                }
                this.accuracy = args.getLong(0);
                this.getLocation();
                return true;
            } else if ("checkGPS".equals(action)) {
                checkGPS();
                return true;
            }
        } catch (Exception e) {
            Log.e(">>>>>", "JSON 出错", e);
            callbackContext.error("sb");
        }

        return false;
    }

    private boolean checkGPS() {
        if (!lm.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
            // 未打开位置开关，可能导致定位失败或定位不准，提示用户或做相应处理
            callbackContext.error("请检查GPS开关");
            return false;
        }
        return true;
    }

    private void getLocation() {

        lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0, locationListener);
    }

    /**
     * 定位查询条件
     * 返回查询条件 ，获取目前设备状态下，最适合的定位方式
     */
    private String getProvider() {
        // 构建位置查询条件
        Criteria criteria = new Criteria();
        // 设置定位精确度 Criteria.ACCURACY_COARSE比较粗略，Criteria.ACCURACY_FINE则比较精细
        //Criteria.ACCURACY_FINE,当使用该值时，在建筑物当中，可能定位不了,建议在对定位要求并不是很高的时候用Criteria.ACCURACY_COARSE，避免定位失败
        // 查询精度：高
        criteria.setAccuracy(Criteria.ACCURACY_MEDIUM);
        // 设置是否要求速度
        criteria.setSpeedRequired(false);
        // 是否查询海拨：否
        criteria.setAltitudeRequired(false);
        // 是否查询方位角 : 否
        criteria.setBearingRequired(false);
        // 是否允许付费：是
        criteria.setCostAllowed(false);
        // 电量要求：低
        criteria.setPowerRequirement(Criteria.POWER_LOW);
        // 返回最合适的符合条件的provider，第2个参数为true说明 , 如果只有一个provider是有效的,则返回当前provider
        return lm.getBestProvider(criteria, true);
    }

    // 位置监听
    private LocationListener locationListener = new LocationListener() {

        /**
         * 位置信息变化时触发
         */
        public void onLocationChanged(Location location) {
            try {

                JSONObject res = new JSONObject();
                res.put("time", location.getTime());

                res.put("latitude", location.getLatitude());
                res.put("longitude", location.getLongitude());
                res.put("accuracy", location.getAccuracy());
                if (location.getAccuracy() < accuracy) {

                    res.put("complete", true);
                    callbackContext.success(res);
                    lm.removeUpdates(this);
                }
                PluginResult r = new PluginResult(PluginResult.Status.OK, res);
                r.setKeepCallback(true);
                callbackContext.sendPluginResult(r);

            } catch (JSONException e) {
                e.printStackTrace();
                callbackContext.error("定位出错，稍后重试");
            }
        }

        /**
         * GPS状态变化时触发
         */
        public void onStatusChanged(String provider, int status, Bundle extras) {
            switch (status) {
                // GPS状态为可见时
                case LocationProvider.AVAILABLE:
                    break;
                // GPS状态为服务区外时
                case LocationProvider.OUT_OF_SERVICE:
                    break;
                // GPS状态为暂停服务时
                case LocationProvider.TEMPORARILY_UNAVAILABLE:
                    break;
            }
        }

        /**
         * GPS开启时触发
         */
        public void onProviderEnabled(String provider) {
            Location location = lm.getLastKnownLocation(provider);
        }

        /**
         * GPS禁用时触发
         */
        public void onProviderDisabled(String provider) {
        }

    };

    private void coolMethod(String message, CallbackContext callbackContext) {
        if (message != null && message.length() > 0) {
            callbackContext.success("无敌大屌哥");
        } else {
            callbackContext.error("Expected one non-empty string argument.");
        }
    }
}